<?php
/**
 * Created by PhpStorm.
 * User: simaguo
 * Date: 2018/6/10
 * Time: 19:42
 */

namespace Simaguo\DS\Lists;


class SqList
{
    protected $list;
    protected $length;
    protected $maxSize;

    public function __construct($size)
    {
        $this->init($size);
    }

    public function __destruct()
    {
        $this->destroy();
    }

    protected function init($size)
    {
        $this->list = array();
        $this->length = 0;
        $this->maxSize = $size;
    }

    public function all()
    {
        return $this->list;
    }

    public function add($elem)
    {
        $length = $this->length();
        $index = $length+1;
        return $this->insert($index, $elem);
    }

    public function destroy()
    {
        $this->list = null;
        $this->length = null;
        $this->maxSize = null;
    }

    public function empty()
    {
        return $this->length === 0;
    }

    public function clear()
    {
        $this->list = array();
        $this->length = 0;
    }

    public function length()
    {
        return $this->length;
    }

    public function get($index)
    {
        $key = $index - 1;
        if ($key < 0 || $key >= $this->length()) {
            //throw new \OutOfBoundsException('');
            return null;
        }

        return $this->list[$key];
    }

    public function locate($elem, $callback = null)
    {
        if (!is_callable($callback)) {
            $callback = function ($a, $b) {
                return $a === $b;
            };
        }
        for ($i = 0; $i < $this->length(); $i++) {
            if ($callback($elem, $this->list[$i])) {
                return $i + 1;
            }
        }

        return 0;
    }


    public function prior($elem)
    {
        for ($i = 0; $i < $this->length(); $i++) {
            if ($elem === $this->list[$i]) {
                if ($i > 0) {
                    return $this->list[$i - 1];
                }

            }
        }

        return null;
    }

    public function next($elem)
    {
        $length = $this->length();
        for ($i = 0; $i < $length; $i++) {
            if ($elem === $this->list[$i]) {
                if ($i < $length - 1) {
                    return $this->list[$i + 1];
                }

            }
        }

        return null;
    }

    public function insert($index, $elem)
    {
        $key = $index - 1;
        $length = $this->length();

        if ($key < 0 || $key > $length) {
            //throw new \OutOfBoundsException('');
            return false;
        }

        if ($length + 1 > $this->maxSize) {
            //throw new \OutOfRangeException('');
            return false;
        }

        for ($i = $key; $i < $length; $i++) {
            $this->list[$i + 1] = $this->list[$i];
        }
        $this->list[$key] = $elem;
        $this->length++;

        return true;
    }

    public function delete($index)
    {
        $key = $index - 1;
        $length = $this->length();

        if ($key < 0 || $key >= $length) {
            //throw new \OutOfBoundsException('');
            return false;
        }

        $elem = $this->list[$key];
        for ($i = $key; $i < $length - 1; $i++) {
            $this->list[$i] = $this->list[$i + 1];
        }
        unset($this->list[$i]);

        $this->length--;

        return $elem;
    }
}